import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/status.dart' as status;
import 'package:Lter/util/toast.dart';
import 'package:Lter/model/user.dart';
import 'dart:convert';
import 'dart:async';

class WebSocket {
  bool ConnectState = false;
  IOWebSocketChannel mChannel;
  String mUrl;
  var mHandleMap = Map<String, Function(dynamic)>();

  onDone() {
    ConnectState = false;
    Toast.show("Socket is onDone");
    Timer(new Duration(seconds: 1), () {
      InitWebSocket(mUrl);
    });
  }

  onError(err) {
    ConnectState = false;
    Toast.show("Websocket Error: " + err.toString());
    Timer(new Duration(seconds: 1), () {
      mChannel.sink.close();
      InitWebSocket(mUrl);
    });
  }

  onData(msg) {
    if (!ConnectState) {
      ConnectState = true;
    }

    if (msg != "iamok") {
      print(msg);

      Map jsonMap = json.decode(msg);
      String sAction = jsonMap["action"];
      if (mHandleMap.containsKey(sAction) == true) {
        mHandleMap[sAction](jsonMap);
      }
    }
  }

  InitWebSocket(String url) async {
    mUrl = url;

    print("new WebSocket: " + mUrl);

    mChannel = new IOWebSocketChannel.connect(mUrl);
    mChannel.stream.listen(this.onData, onError: onError, onDone: onDone);
  }

  WebSocket(String url) {
    InitWebSocket(url);
  }

  void Release() {
    print("Websocket Release");

    mChannel.sink.close(status.goingAway);
  }

  bool GetState() {
    return ConnectState;
  }

  void Send(String action, User user, Map<String, dynamic> dataMap) {
    if (GetState()) {
      Map<String, dynamic> sendJsonMap = Map<String, dynamic>();
      sendJsonMap["action"] = action;
      sendJsonMap["username"] = user.username;
      sendJsonMap["passwd"] = user.password;
      if (dataMap != null) {
        sendJsonMap["data"] = dataMap;
      }

      var msg = json.encode(sendJsonMap);
      mChannel.sink.add(msg);
      print("Websocket Send: " + msg);
    } else {
      Send(action, user, dataMap);
    }
  }

  bool AddHandle(String action, voidCallback(dynamic)) {
    print("Websocket AddHandle: " + action);

    if (mHandleMap.containsKey(action) == true) {
      mHandleMap.remove(action);
    }
    mHandleMap[action] = voidCallback;
    return true;
  }

  bool RemoveHandle(String action) {
    print("Websocket RemoveHandle: " + action);

    if (mHandleMap.containsKey(action) == true) {
      mHandleMap.remove(action);
      return true;
    }
    return false;
  }
}
